
package com.cgmnx.admin.web.controller.login;

import com.cgmnx.admin.biz.log.OperationLogBiz;
import com.cgmnx.admin.biz.login.LoginBiz;
import com.cgmnx.admin.biz.rbac.ResourceBiz;
import com.cgmnx.admin.common.bean.ApiRes;
import com.cgmnx.admin.common.util.EncryptionUtil;
import com.cgmnx.admin.common.util.WebUtils;
import com.cgmnx.admin.dao.entity.rbac.OperationLogEntity;
import com.cgmnx.admin.dao.entity.rbac.ResourceEntity;
import com.cgmnx.admin.dao.entity.rbac.UserEntity;
import com.cgmnx.admin.model.enums.rbac.OperationType;
import com.cgmnx.admin.web.CookieUtil;
import com.cgmnx.admin.web.model.param.LoginParam;
import com.google.common.base.Optional;
import com.google.common.primitives.Ints;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.CookieValue;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

/**
 * 运营端登录
 */
@Slf4j
@Controller
public class LoginController {

    @Value("${logout.rollback.url}")
    public String logout_rollback_url;
    @Autowired
    private LoginBiz loginBiz;

    @Autowired
    private ResourceBiz resourceBiz;
    @Autowired
    private OperationLogBiz operationLogBiz;
    private String login_rollback_url = "/cgmnx/account/index.html";

    @RequestMapping(value = "/cgmnx/login/login.json", method = RequestMethod.POST)
    @ResponseBody
    public ApiRes login(@Valid @RequestBody LoginParam loginParam, BindingResult bindingResult, HttpServletResponse response) {

        if (bindingResult.hasErrors()) {
            return ApiRes.returnFail(WebUtils.resolveBindingResult(bindingResult));
        }

        // 根据用户名查询是否有对应的用户
        Optional<UserEntity> optional = loginBiz.login(loginParam.getUserEmail(),
                loginParam.getPassword());

        return redirect(response, optional);
    }


    private ApiRes redirect(HttpServletResponse response, Optional<UserEntity> optional) {
        if (!optional.isPresent()) {
            return ApiRes.returnFail("该用户不存在或者密码不对");
        }

        setCookieInfo(response, optional.get());

        List<ResourceEntity> resourceEntities = resourceBiz.queryByUserId(optional.get().getUserId());

        Collections.sort(resourceEntities, new Comparator<ResourceEntity>() {
            @Override
            public int compare(ResourceEntity o1, ResourceEntity o2) {
                return Ints.compare(o1.getId(), o2.getId());
            }
        });

        if (CollectionUtils.isNotEmpty(resourceEntities)) {
            return ApiRes.returnSuccess(resourceEntities.get(0).getUri());
        }

        return ApiRes.returnSuccess(login_rollback_url);
    }

    private void setCookieInfo(HttpServletResponse response, UserEntity userEntity) {
        // 写cookie
        CookieUtil.setUCookie(response, userEntity.getUserId());

        long loginTime = System.currentTimeMillis();

        CookieUtil.setTCookie(response, String.valueOf(loginTime));

        String validation = EncryptionUtil.encryptCookie(userEntity.getUserId(), loginTime, userEntity.getSalt());// 利用userId,登录时间加密对cookie进行合法性验证
        CookieUtil.setVCookie(response, validation);
    }


    /**
     * 用户退出
     *
     * @return
     */
    @RequestMapping(value = "/cgmnx/login/logout.json", method = RequestMethod.GET)
    public ModelAndView logout(@CookieValue("_u") String uCookie,
                               @CookieValue("_t") String tCookie,
                               @CookieValue("_v") String vCookie) {

        CookieUtil.clearCookie(uCookie);
        CookieUtil.clearCookie(tCookie);
        CookieUtil.clearCookie(vCookie);

        saveLog(uCookie);
        log.info("退出地址:{}", logout_rollback_url);
        // 注销登录
        return new ModelAndView("redirect:" + logout_rollback_url);
    }


    public void saveLog(String userId) {
        try {
            // 获取request对象
            HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
            //获取请求ip
            String ip = WebUtils.getRealIP(request);

            OperationLogEntity logEntity = new OperationLogEntity();
            logEntity.setContent("退出系统");
            logEntity.setOperationType(OperationType.LOGIN);
            logEntity.setOperatorName(userId);
            logEntity.setIp(ip);

            logEntity.setCreateUser(userId);
            logEntity.setUpdateUser(userId);

            operationLogBiz.save(logEntity);
        } catch (Exception e) {
            log.info("登录时候错误,", e);
        }

    }


    public String getLogout_rollback_url() {
        return logout_rollback_url;
    }

    public void setLogout_rollback_url(String logout_rollback_url) {
        this.logout_rollback_url = logout_rollback_url;
    }
}